package com.db.ionio.nio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class FileNIOServer {
    private final int port;
    private final String dstFileName;

    public FileNIOServer(int port, String dstFileName) {
        this.port = port;
        this.dstFileName = dstFileName;
    }

    public void run() {
        System.out.println("Waiting for client connection ...");
        try (
                ServerSocketChannel channel = ServerSocketChannel.open();
                FileChannel out = new FileOutputStream(new File(dstFileName)).getChannel()
        ) {
            CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
            channel.socket().bind(new InetSocketAddress(port));
            SocketChannel socketChannel = channel.accept();

            ByteBuffer byteBuffer = ByteBuffer.allocate(8);
            socketChannel.read(byteBuffer);
            long fileSize = byteBuffer.getLong(0);
            byteBuffer.clear();
            System.out.format("file size is %d%n", fileSize);

            out.transferFrom(socketChannel, 0, fileSize);

            socketChannel.write(encoder.encode(CharBuffer.wrap("done")));
            System.out.println("done");

        } catch (IOException ioException) {
            ioException.printStackTrace();
            System.err.println(ioException.getMessage());
        } catch (NullPointerException nullPointerException) {
            nullPointerException.printStackTrace();
            System.err.println(nullPointerException.getMessage());
        }
    }
}
